/*
*Copyright 2021-2023 NERCIS
*
*Licensed under the Apache License, Version 2.0 (the "License");
*you may not use this file except in compliance with the License.
*You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing, software
*distributed under the License is distributed on an "AS IS" BASIS,
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*See the License for the specific language governing permissions and
*limitations under the License.
*/

package cn.ac.nercis.pes.community.component.controls;

import cn.ac.nercis.pes.common.utils.DataUtils;
import cn.ac.nercis.pes.community.component.dialog.MessageDialog;
import cn.ac.nercis.pes.community.component.dialog.MessageType;
import cn.ac.nercis.pes.community.manager.RealTimeSaveManager;
import cn.ac.nercis.pes.community.mapper.evaluation.EvaluationProcessViewMapper;
import cn.ac.nercis.pes.community.model.vo.evaluation.EvaluationStageVO;
import cn.ac.nercis.pes.community.support.controls.JFXPopup;
import cn.ac.nercis.pes.community.support.event.CommonCallback;
import cn.ac.nercis.pes.model.dto.evaluation.prepare.EvaluationStageDTO;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import lombok.extern.slf4j.Slf4j;

import java.time.temporal.ChronoUnit;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

/**
 * 测评计划信息控件
 * @author zpy
 * @version 1.0.0
 */
@Slf4j
public class EvalPlanControl extends VBox {
    private final static String PREPARE = "准备过程";
    private final static String PLANNING = "方案编制过程";
    private final static String EVALUATION = "现场测评过程";
    private final static String REPORT = "分析与报告编制过程";
    private final static Integer LABEL_COLUMN_INDEX = 0;
    private final static Integer TEXT_COLUMN_INDEX = 1;

    private final DatePicker prepareStartDP= new DatePicker();
    private final DatePicker prepareEndDP= new DatePicker();
    private final DatePicker planningStartDP= new DatePicker();
    private final DatePicker planningEndDP= new DatePicker();
    private final DatePicker evaluationStartDP= new DatePicker();
    private final DatePicker evaluationEndDP= new DatePicker();
    private final DatePicker reportStartDP= new DatePicker();
    private final DatePicker reportEditDP= new DatePicker();

    private final TextArea projectStartTxt = new TextArea();
    private final TextArea collectAnalyzeTxt = new TextArea();
    private final TextArea toolPrepareTxt = new TextArea();

    private final TextArea assetDefineTxt = new TextArea();
    private final TextArea targetDefineTxt = new TextArea();
    private final TextArea checkPointDefineTxt = new TextArea();
    private final TextArea contentDefineTxt = new TextArea();
    private final TextArea schemeMakeTxt = new TextArea();

    private final TextArea implementPrepareTxt = new TextArea();
    private final TextArea sceneRecordTxt = new TextArea();
    private final TextArea resultDefineTxt = new TextArea();

    private final TextArea unitEvalTxt = new TextArea();
    private final TextArea overallEvalTxt = new TextArea();
    private final TextArea quantifyEvalTxt = new TextArea();
    private final TextArea riskAnalyzeTxt = new TextArea();
    private final TextArea evalConclusionTxt = new TextArea();
    private final TextArea secretReportTxt = new TextArea();

    protected final SimpleBooleanProperty editModel = new SimpleBooleanProperty(false);
    private final EvaluationStageVO evaluationStageVO = new EvaluationStageVO();
    private final RealTimeSaveManager realTimeSaveManager=new RealTimeSaveManager(this::fastSave);

    private CommonCallback realTimeSave;
    private GridPane prepareGrid;
    private GridPane planningGrid;
    private GridPane evaluationGrid;
    private GridPane reportGrid;

    public EvalPlanControl(){
        initPlanControl();
        initDatePicker("pes-datepicker","size-small");
        initText("pes-text-field");
    }

    public void fastSave(){
        if(Objects.nonNull(realTimeSave) && editModel.get()){
            realTimeSave.action();
        }
    }

    public void setRealTimeSave(CommonCallback save){
        realTimeSave = save;
    }

    public void loadContent(EvaluationStageDTO stage){
        this.editModel.set(false);
        evaluationStageVO.setSystemId(stage.getSystemId());
        evaluationStageVO.setPreparationStartDate(stage.getPreparationStartDate());
        evaluationStageVO.setPreparationEndDate(stage.getPreparationEndDate());
        evaluationStageVO.setCompilationStartDate(stage.getCompilationStartDate());
        evaluationStageVO.setCompilationEndDate(stage.getCompilationEndDate());
        evaluationStageVO.setEvaluationStartDate(stage.getEvaluationStartDate());
        evaluationStageVO.setEvaluationEndDate(stage.getEvaluationEndDate());
        evaluationStageVO.setAnalysisStartDate(stage.getAnalysisStartDate());
        evaluationStageVO.setAnalysisEndDate(stage.getAnalysisEndDate());

        evaluationStageVO.setProjectStart(stage.getPreparationPlan().getProjectStart());
        evaluationStageVO.setCollectAnalyze(stage.getPreparationPlan().getCollectAnalyze());
        evaluationStageVO.setToolPrepare(stage.getPreparationPlan().getToolPrepare());

        evaluationStageVO.setAssetDefine(stage.getCompilationPlan().getAssetDefine());
        evaluationStageVO.setTargetDefine(stage.getCompilationPlan().getTargetDefine());
        evaluationStageVO.setCheckPointDefine(stage.getCompilationPlan().getCheckPointDefine());
        evaluationStageVO.setContentDefine(stage.getCompilationPlan().getContentDefine());
        evaluationStageVO.setSchemeMake(stage.getCompilationPlan().getSchemeMake());

        evaluationStageVO.setImplementPrepare(stage.getEvaluationPlan().getImplementPrepare());
        evaluationStageVO.setSceneRecord(stage.getEvaluationPlan().getSceneRecord());
        evaluationStageVO.setResultDefine(stage.getEvaluationPlan().getResultDefine());

        evaluationStageVO.setUnitEval(stage.getAnalysisPlan().getUnitEval());
        evaluationStageVO.setOverallEval(stage.getAnalysisPlan().getOverallEval());
        evaluationStageVO.setQuantifyEval(stage.getAnalysisPlan().getQuantifyEval());
        evaluationStageVO.setRiskAnalyze(stage.getAnalysisPlan().getRiskAnalyze());
        evaluationStageVO.setEvalConclusion(stage.getAnalysisPlan().getEvalConclusion());
        evaluationStageVO.setSecretReport(stage.getAnalysisPlan().getSecretReport());
        this.editModel.set(true);
    }

    public boolean validContent(StackPane page){
        if(!prepareValid(page)){
            return false;
        }
        if(!planningValid(page)){
            return false;
        }
        if(!evaluationValid(page)){
            return false;
        }
        return reportValid(page);
    }

    public EvaluationStageDTO getData(){
        return EvaluationProcessViewMapper.INSTANCE.toEvaluationStageDTO(evaluationStageVO);
    }

    private boolean prepareValid(StackPane page){
        if(Objects.isNull(evaluationStageVO.getPreparationStartDate())
                || Objects.isNull(evaluationStageVO.getPreparationEndDate())){
            MessageDialog.builder()
                    .withContainer(page)
                    .withType(MessageType.WARN).withMessage("准备过程，测评计划不允许为空")
                    .build().show();
            return false;
        }
        long between =  DataUtils.between(evaluationStageVO.getPreparationStartDate(),
                evaluationStageVO.getPreparationEndDate(), ChronoUnit.DAYS);
        if(between < 1){
            MessageDialog.builder()
                    .withContainer(page)
                    .withType(MessageType.WARN).withMessage("准备过程，测评计划结束日期必须大于开始日期")
                    .build().show();
            return false;
        }
        return true;
    }

    private boolean planningValid(StackPane page){
        if(Objects.isNull(evaluationStageVO.getCompilationStartDate())
                || Objects.isNull(evaluationStageVO.getCompilationEndDate())){
            MessageDialog.builder()
                    .withContainer(page)
                    .withType(MessageType.WARN).withMessage("方案编制过程，测评计划不允许为空")
                    .build().show();
            return false;
        }
        long between =  DataUtils.between(evaluationStageVO.getCompilationStartDate(),
                evaluationStageVO.getCompilationEndDate(), ChronoUnit.DAYS);
        if(between < 1){
            MessageDialog.builder()
                    .withContainer(page)
                    .withType(MessageType.WARN).withMessage("方案编制过程，测评计划结束日期必须大于开始日期")
                    .build().show();
            return false;
        }
        return true;
    }

    private boolean evaluationValid(StackPane page){
        if(Objects.isNull(evaluationStageVO.getEvaluationStartDate())
                || Objects.isNull(evaluationStageVO.getEvaluationEndDate())){
            MessageDialog.builder()
                    .withContainer(page)
                    .withType(MessageType.WARN).withMessage("测评实施过程，测评计划不允许为空")
                    .build().show();
            return false;
        }
        long between =  DataUtils.between(evaluationStageVO.getEvaluationStartDate(),
                evaluationStageVO.getEvaluationEndDate(), ChronoUnit.DAYS);
        if(between < 1){
            MessageDialog.builder()
                    .withContainer(page)
                    .withType(MessageType.WARN).withMessage("测评实施过程，测评计划结束日期必须大于开始日期")
                    .build().show();
            return false;
        }
        return true;
    }

    private boolean reportValid(StackPane page){
        if(Objects.isNull(evaluationStageVO.getAnalysisStartDate())
                || Objects.isNull(evaluationStageVO.getAnalysisEndDate())){
            MessageDialog.builder()
                    .withContainer(page)
                    .withType(MessageType.WARN).withMessage("分析与报告编制过程，测评计划不允许为空")
                    .build().show();
            return false;
        }
        long between =  DataUtils.between(evaluationStageVO.getAnalysisStartDate(),
                evaluationStageVO.getAnalysisEndDate(), ChronoUnit.DAYS);
        if(between < 1){
            MessageDialog.builder()
                    .withContainer(page)
                    .withType(MessageType.WARN).withMessage("分析与报告编制过程，测评计划结束日期必须大于开始日期")
                    .build().show();
            return false;
        }
        return true;
    }

    private void initDatePicker(String... styleCss){
        Stream.of(prepareStartDP,prepareEndDP,planningStartDP,planningEndDP,
                        evaluationStartDP,evaluationEndDP,reportStartDP,reportEditDP)
                .forEach(item-> {
                    item.getStyleClass().addAll(styleCss);
                    item.setEditable(false);
                });
        Stream.of(prepareStartDP,planningStartDP,evaluationStartDP,reportStartDP)
                .forEach(item-> item.setPromptText("起始时间"));
        Stream.of(prepareEndDP,planningEndDP,evaluationEndDP,reportEditDP)
                .forEach(item-> item.setPromptText("结束时间"));
        prepareStartDP.valueProperty().bindBidirectional(evaluationStageVO.preparationStartDateProperty());
        prepareEndDP.valueProperty().bindBidirectional(evaluationStageVO.preparationEndDateProperty());
        planningStartDP.valueProperty().bindBidirectional(evaluationStageVO.compilationStartDateProperty());
        planningEndDP.valueProperty().bindBidirectional(evaluationStageVO.compilationEndDateProperty());
        evaluationStartDP.valueProperty().bindBidirectional(evaluationStageVO.evaluationStartDateProperty());
        evaluationEndDP.valueProperty().bindBidirectional(evaluationStageVO.evaluationEndDateProperty());
        reportStartDP.valueProperty().bindBidirectional(evaluationStageVO.analysisStartDateProperty());
        reportEditDP.valueProperty().bindBidirectional(evaluationStageVO.analysisEndDateProperty());

        realTimeSaveManager.listenerDateChange(prepareStartDP,prepareEndDP,planningStartDP,planningEndDP,
                evaluationStartDP,evaluationEndDP,reportStartDP,reportEditDP);
    }

    private void initText(String... styleCss){
        Stream.of(projectStartTxt,collectAnalyzeTxt,toolPrepareTxt,
                        assetDefineTxt,targetDefineTxt,checkPointDefineTxt,contentDefineTxt,schemeMakeTxt,
                        implementPrepareTxt,sceneRecordTxt,resultDefineTxt,
                        unitEvalTxt,overallEvalTxt,quantifyEvalTxt,riskAnalyzeTxt,evalConclusionTxt,secretReportTxt)
                .forEach(item-> {
                    item.getStyleClass().addAll(styleCss);
                    item.setWrapText(true);
                });
        projectStartTxt.textProperty().bindBidirectional(evaluationStageVO.projectStartProperty());
        collectAnalyzeTxt.textProperty().bindBidirectional(evaluationStageVO.collectAnalyzeProperty());
        toolPrepareTxt.textProperty().bindBidirectional(evaluationStageVO.toolPrepareProperty());

        assetDefineTxt.textProperty().bindBidirectional(evaluationStageVO.assetDefineProperty());
        targetDefineTxt.textProperty().bindBidirectional(evaluationStageVO.targetDefineProperty());
        checkPointDefineTxt.textProperty().bindBidirectional(evaluationStageVO.checkPointDefineProperty());
        contentDefineTxt.textProperty().bindBidirectional(evaluationStageVO.contentDefineProperty());
        schemeMakeTxt.textProperty().bindBidirectional(evaluationStageVO.schemeMakeProperty());

        implementPrepareTxt.textProperty().bindBidirectional(evaluationStageVO.implementPrepareProperty());
        sceneRecordTxt.textProperty().bindBidirectional(evaluationStageVO.sceneRecordProperty());
        resultDefineTxt.textProperty().bindBidirectional(evaluationStageVO.resultDefineProperty());

        unitEvalTxt.textProperty().bindBidirectional(evaluationStageVO.unitEvalProperty());
        overallEvalTxt.textProperty().bindBidirectional(evaluationStageVO.overallEvalProperty());
        quantifyEvalTxt.textProperty().bindBidirectional(evaluationStageVO.quantifyEvalProperty());
        riskAnalyzeTxt.textProperty().bindBidirectional(evaluationStageVO.riskAnalyzeProperty());
        evalConclusionTxt.textProperty().bindBidirectional(evaluationStageVO.evalConclusionProperty());
        secretReportTxt.textProperty().bindBidirectional(evaluationStageVO.secretReportProperty());

        realTimeSaveManager.listenerTextChange(projectStartTxt,collectAnalyzeTxt,toolPrepareTxt,
                assetDefineTxt,targetDefineTxt,checkPointDefineTxt,contentDefineTxt,schemeMakeTxt,
                implementPrepareTxt,sceneRecordTxt,resultDefineTxt,
                unitEvalTxt,overallEvalTxt,quantifyEvalTxt,riskAnalyzeTxt,evalConclusionTxt,secretReportTxt);
    }

    private void initPlanControl(){
        this.renderPlanControl(PREPARE,prepareStartDP,prepareEndDP);
        this.renderPlanControl(PLANNING,planningStartDP,planningEndDP);
        this.renderPlanControl(EVALUATION,evaluationStartDP,evaluationEndDP);
        this.renderPlanControl(REPORT,reportStartDP,reportEditDP);
    }

    private void renderPlanControl(String planName,DatePicker start,DatePicker end){
        var block = new VBox();
        block.getStyleClass().add("content-block");
        block.getChildren().addAll(generateBlockTitle(planName),generateBlockContent(start, end));
        this.getChildren().add(block);
    }

    private HBox generateBlockTitle(String planName){
        var blockTitle = new HBox();
        blockTitle.setAlignment(Pos.CENTER_LEFT);
        blockTitle.getStyleClass().add("block-title");
        blockTitle.getChildren().add(new Label(planName));
        var tools = new HBox();
        HBox.setHgrow(tools, Priority.SOMETIMES);
        tools.setAlignment(Pos.CENTER_RIGHT);
        var btn = new Button("测评工作内容");
        btn.getStyleClass().add("link-button");
        btn.setTooltip(new Tooltip("测评工作内容"));
        btn.setUserData(planName);
        btn.setOnAction(this::showWorkContent);
        tools.getChildren().add(btn);
        blockTitle.getChildren().add(tools);
        return blockTitle;
    }

    private VBox generateBlockContent(DatePicker start,DatePicker end){
        var block = new VBox();
        block.getStyleClass().add("block-border");
        block.setPadding(new Insets(15));
        var row = new HBox();
        row.getStyleClass().add("eval-common-row-box");
        var label = new HBox();
        label.getStyleClass().add("eval-common-label-box");
        label.getChildren().add(new Label("测评计划"));
        row.getChildren().add(label);

        var text = new HBox();
        text.getStyleClass().add("eval-common-text-box");
        text.setSpacing(5);
        HBox.setHgrow(text,Priority.SOMETIMES);
        text.setAlignment(Pos.CENTER_LEFT);
        text.getChildren().addAll(start,new Label("至"),end);
        row.getChildren().add(text);

        block.getChildren().add(row);
        return block;
    }

    private void showWorkContent(ActionEvent event){
        if(event.getSource() instanceof Button btn && Objects.nonNull(btn.getUserData())){
            String planName = btn.getUserData().toString();
            switch (planName){
                case PREPARE -> showWorkContent(planName,getPrepareGrid());
                case PLANNING -> showWorkContent(planName,getPlanningGrid());
                case EVALUATION -> showWorkContent(planName,getEvaluationGrid());
                case REPORT -> showWorkContent(planName,getReportGrid());
            }
        }
    }

    private void showWorkContent(String planName, Region content){
        VBox body = new VBox();
        body.setPadding(new Insets(10));
        body.setSpacing(3);
        body.getChildren().addAll(content);
        var popOver = new JFXPopup(body);
        popOver.show(this, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT,
                60,0);
    }

    private HBox generateWorkTitle(String planName){
        var blockTitle = new HBox();
        blockTitle.setAlignment(Pos.CENTER);
        blockTitle.getStyleClass().add("block-title");
        blockTitle.getChildren().add(new Label(planName));
        return blockTitle;
    }

    private GridPane getPrepareGrid(){
        if(Objects.isNull(this.prepareGrid)){
            this.prepareGrid = new GridPane();
            this.prepareGrid.getStyleClass().add("pes-plan-grid");
            this.definedGridStructure(this.prepareGrid,3);
            this.buildTitleGrid(this.prepareGrid);
            var rowIndex = new AtomicInteger(1);
            generateLabelCell(this.prepareGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"项目启动");
            generateTextCell(this.prepareGrid,rowIndex.getAndIncrement(),this.projectStartTxt);

            generateLabelCell(this.prepareGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"信息收集和分析");
            generateTextCell(this.prepareGrid,rowIndex.getAndIncrement(),this.collectAnalyzeTxt);

            generateLabelCell(this.prepareGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"工具和文档准备");
            generateTextCell(this.prepareGrid,rowIndex.getAndIncrement(),this.toolPrepareTxt);
        }
        return this.prepareGrid;
    }

    private GridPane getPlanningGrid(){
        if(Objects.isNull(this.planningGrid)){
            this.planningGrid = new GridPane();
            this.planningGrid.getStyleClass().add("pes-plan-grid");
            this.definedGridStructure(this.planningGrid,5);
            this.buildTitleGrid(this.planningGrid);
            var rowIndex = new AtomicInteger(1);
            generateLabelCell(this.planningGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"测评对象确定");
            generateTextCell(this.planningGrid,rowIndex.getAndIncrement(),this.assetDefineTxt);

            generateLabelCell(this.planningGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"测评指标确定");
            generateTextCell(this.planningGrid,rowIndex.getAndIncrement(),this.targetDefineTxt);

            generateLabelCell(this.planningGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"测评检查点确定");
            generateTextCell(this.planningGrid,rowIndex.getAndIncrement(),this.checkPointDefineTxt);

            generateLabelCell(this.planningGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"测评内容确定");
            generateTextCell(this.planningGrid,rowIndex.getAndIncrement(),this.contentDefineTxt);

            generateLabelCell(this.planningGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"测评方案编制");
            generateTextCell(this.planningGrid,rowIndex.getAndIncrement(),this.schemeMakeTxt);
        }
        return this.planningGrid;
    }

    private GridPane getEvaluationGrid(){
        if(Objects.isNull(this.evaluationGrid)){
            this.evaluationGrid = new GridPane();
            this.evaluationGrid.getStyleClass().add("pes-plan-grid");
            this.definedGridStructure(this.evaluationGrid,3);
            this.buildTitleGrid(this.evaluationGrid);
            var rowIndex = new AtomicInteger(1);
            generateLabelCell(this.evaluationGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"现场测评准备");
            generateTextCell(this.evaluationGrid,rowIndex.getAndIncrement(),this.implementPrepareTxt);

            generateLabelCell(this.evaluationGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"现场测评和结果记录");
            generateTextCell(this.evaluationGrid,rowIndex.getAndIncrement(),this.sceneRecordTxt);

            generateLabelCell(this.evaluationGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"测评结果确认和资料归还");
            generateTextCell(this.evaluationGrid,rowIndex.getAndIncrement(),this.resultDefineTxt);
        }
        return this.evaluationGrid;
    }

    private GridPane getReportGrid(){
        if(Objects.isNull(this.reportGrid)){
            this.reportGrid = new GridPane();
            this.reportGrid.getStyleClass().add("pes-plan-grid");
            this.definedGridStructure(this.reportGrid,6);
            this.buildTitleGrid(this.reportGrid);
            var rowIndex = new AtomicInteger(1);
            generateLabelCell(this.reportGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"单元测评");
            generateTextCell(this.reportGrid,rowIndex.getAndIncrement(),this.unitEvalTxt);

            generateLabelCell(this.reportGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"整体测评");
            generateTextCell(this.reportGrid,rowIndex.getAndIncrement(),this.overallEvalTxt);

            generateLabelCell(this.reportGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"量化评估");
            generateTextCell(this.reportGrid,rowIndex.getAndIncrement(),this.quantifyEvalTxt);

            generateLabelCell(this.reportGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"风险分析");
            generateTextCell(this.reportGrid,rowIndex.getAndIncrement(),this.riskAnalyzeTxt);

            generateLabelCell(this.reportGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"评估结论形成");
            generateTextCell(this.reportGrid,rowIndex.getAndIncrement(),this.evalConclusionTxt);

            generateLabelCell(this.reportGrid,rowIndex.get(),LABEL_COLUMN_INDEX,"密评报告编制");
            generateTextCell(this.reportGrid,rowIndex.getAndIncrement(),this.secretReportTxt);
        }
        return this.reportGrid;
    }

    private void definedGridStructure(GridPane gridPane,int dataRowCount){
        gridPane.getColumnConstraints().add(new ColumnConstraints(120));
        var contentColumn = new ColumnConstraints();
        contentColumn.setMinWidth(350);
        contentColumn.setHgrow(Priority.SOMETIMES);
        gridPane.getColumnConstraints().add(contentColumn);

        var titleRow = new RowConstraints(30);
        gridPane.getRowConstraints().add(titleRow);
        for(int index=0;index<dataRowCount;index++){
            gridPane.getRowConstraints().add(new RowConstraints(80));
        }
    }

    private void buildTitleGrid(GridPane gridPane){
        generateLabelCell(gridPane,0,LABEL_COLUMN_INDEX,"测评流程");
        generateLabelCell(gridPane,0,TEXT_COLUMN_INDEX,"测评工作内容");
    }

    private void generateLabelCell(GridPane gridPane, int rowIndex,int columnIndex,String content){
        var cell = new VBox();
        cell.setAlignment(Pos.CENTER);
        cell.setPadding(new Insets(5,5,5,5));
        if(rowIndex > 0 && columnIndex > 0){
            cell.getStyleClass().add("top-left-border");
        } else if (rowIndex > 0) {
            cell.getStyleClass().add("top-border");
        } else if (columnIndex > 0) {
            cell.getStyleClass().add("left-border");
        }
        if(rowIndex ==0){
            cell.getStyleClass().add("title-cell");
        }else{
            cell.getStyleClass().add("data-cell");
        }
        var textLabel = new Label(content);
        textLabel.setWrapText(true);
        cell.getChildren().add(textLabel);

        gridPane.getChildren().add(cell);

        GridPane.setRowIndex(cell,rowIndex);
        GridPane.setColumnIndex(cell,columnIndex);
    }

    private void generateTextCell(GridPane gridPane,int rowIndex, TextArea text){
        var cell = new VBox();
        cell.setAlignment(Pos.CENTER);
        cell.setPadding(new Insets(5,5,5,5));
        if(rowIndex > 0){
            cell.getStyleClass().add("top-left-border");
        } else {
            cell.getStyleClass().add("left-border");
        }
        if(rowIndex ==0){
            cell.getStyleClass().add("title-cell");
        }else{
            cell.getStyleClass().add("data-cell");
        }
        cell.getChildren().add(text);
        GridPane.setRowIndex(cell,rowIndex);
        GridPane.setColumnIndex(cell,TEXT_COLUMN_INDEX);

        gridPane.getChildren().add(cell);
    }
}